package com.lzh.hosp.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzh.hosp.model.*;
import com.lzh.hosp.model.dto.PrescriptionQueryDto;
import com.lzh.hosp.service.*;
import com.lzh.hosp.mapper.PrescriptionMapper;
import com.lzh.hosp.utils.RedisCache;
import com.lzh.hosp.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
* @author 59399
* @description 针对表【prescription】的数据库操作Service实现
* @createDate 2023-04-08 11:02:01
*/
@Service
public class PrescriptionServiceImpl extends ServiceImpl<PrescriptionMapper, Prescription>
    implements PrescriptionService{

    @Autowired
    private PrescriptionDetailService prescriptionDetailService;

    @Autowired
    private MedicineWarehouseService medicineWarehouseService;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private MedicineService medicineService;

    @Autowired
    private DoctorService doctorService;

    @Autowired
    private DictService dictService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private WebSocketServer socketServer;


    @Override
    @Transactional
    public boolean savePrescription(Prescription prescription, List<PrescriptionDetail> prescriptionDetailList) {
        //设置处方信息的其他值
        prescription.setStatus(0);
        //插入处方信息
        int insert = baseMapper.insert(prescription);

        double totalPrice = 0;

        //插入处方药品信息
        for (PrescriptionDetail prescriptionDetail : prescriptionDetailList) {
            //判断药品余量是否充足 不充足则抛出异常 进行事务回滚
            Integer amount = medicineWarehouseService.getAllAmountByMedId(prescriptionDetail.getMedId());
            Integer prescriptionDetailAmount = prescriptionDetail.getAmount();
            if (amount<prescriptionDetailAmount){
                throw new RuntimeException("余量不足");
            }else{
                //查询出药品的价格
                Medicine medicine = medicineService.getById(prescriptionDetail.getMedId());
                double singlePrice = medicine.getPrice();
                totalPrice+=prescriptionDetailAmount*singlePrice;

                //设置其他值
                prescriptionDetail.setTotalPrice(singlePrice*prescriptionDetailAmount);
                prescriptionDetail.setPrescriptionId(prescription.getId());
                prescriptionDetail.setCreateTime(new Date());
                prescription.setUpdateTime(new Date());
                prescriptionDetailService.save(prescriptionDetail);

                //修改库存数量
                QueryWrapper<MedicineWarehouse> wareHouseWrapper = new QueryWrapper<>();
                wareHouseWrapper.eq("med_id",medicine.getId());
                wareHouseWrapper.orderByAsc("term_of_validity");
                //减少库存数量
                List<MedicineWarehouse> medicineWarehouseList = medicineWarehouseService.list(wareHouseWrapper);
                for (MedicineWarehouse medicineWarehouse : medicineWarehouseList) {
                    Integer warehouseAmount = medicineWarehouse.getAmount();
                    if (warehouseAmount >=prescriptionDetailAmount){
                        medicineWarehouse.setAmount(warehouseAmount-prescriptionDetailAmount);
                        prescriptionDetailAmount = 0;
                    }else{
                        medicineWarehouse.setAmount(0);
                        prescriptionDetailAmount = prescriptionDetailAmount - warehouseAmount;
                    }
                    medicineWarehouseService.updateById(medicineWarehouse);
                    if (prescriptionDetailAmount==0){
                        break;
                    }
                }
            }
        }

        //修改订单信息
        OrderInfo orderInfo = orderInfoService.getById(prescription.getOrderInfoId());
        orderInfo.setOrderStatus(4);//4表示就诊完成
        boolean flag = orderInfoService.updateById(orderInfo);

        //更新处方的总金额
        prescription.setTotalPrice(totalPrice);
        baseMapper.updateById(prescription);

        //清除redis中的就诊人信息
        boolean b = redisCache.deleteObject("doctor:" + prescription.getDocId() + ":visit");

        if (flag!=true||insert!=1||b!=true){
            throw new RuntimeException("插入失败");
        }

        return true;
    }

    @Override
    public List<Prescription> getPrescription(PrescriptionQueryDto prescriptionQueryDto) {
        Long userId = prescriptionQueryDto.getUserId();
        String cardNo = prescriptionQueryDto.getCardNo();
        String createTime = prescriptionQueryDto.getCreateTime();
        Integer status = prescriptionQueryDto.getStatus();

        //构造查询条件
        QueryWrapper<Prescription> wrapper = new QueryWrapper<>();
        wrapper.eq(!StringUtils.isEmpty(cardNo),"card_no",cardNo);
        wrapper.eq(!StringUtils.isEmpty(createTime),"create_time",createTime);
        wrapper.eq(!StringUtils.isEmpty(status),"status",status);
        wrapper.inSql(!StringUtils.isEmpty(userId),"id","select prescription.id from prescription INNER JOIN patient on patient.card_no = prescription.card_no INNER JOIN sys_user on sys_user.id = patient.user_id where sys_user.id = "+userId);

        List<Prescription> prescriptionList = baseMapper.selectList(wrapper);
        //设置其他值
        for (Prescription prescription : prescriptionList) {
            //根据docId查出医生名和科室编号
            Integer docId = prescription.getDocId();
            Doctor doctor = doctorService.getById(docId);
            //根据科室编号查询科室名
            String depname = dictService.getDictName(doctor.getDepcode());
            String docname = doctor.getUsername();

            Map<String,Object> params = new HashMap<>();
            params.put("depname",depname);
            params.put("docname",docname);
            prescription.setParams(params);
        }
        return prescriptionList;
    }

    @Override
    @Transactional
    public boolean pay(String prescriptionId) {
        //查询出处方
        Prescription prescription = baseMapper.selectById(prescriptionId);
        prescription.setStatus(1);

        int update = baseMapper.updateById(prescription);

        //向药库段发送抓药请求
        if (update==1){
            Message message = new Message();
            message.setAction("notifyDrugstoreMedicineCollection");
            Map<String,Object> params = new HashMap<>();
            params.put("prescriptionId",prescriptionId);
            message.setParams(params);
            try {
                socketServer.onMessage(JSON.toJSONString(message),null);
            } catch (Exception e) {
                throw new RuntimeException("药房没开");
            }
        }
        return true;
    }

    @Override
    public boolean finishMedicationCollection(String prescriptionId,Long userId) {
        List<String> prescriptionList = (List<String>) redisCache.getCacheObject("drugstore:"+userId+":wait");
        boolean flag = prescriptionList.remove(prescriptionId);
        if (flag==false){
            return false;
        }
        //更新
        redisCache.setCacheObject("drugstore:"+userId+":wait",prescriptionList);

        //将待取药的病人放到redis
        List<String> prescriptionFinishList = (List<String>) redisCache.getCacheObject("drugstore:"+userId+":finish");
        if (StringUtils.isEmpty(prescriptionFinishList)){
            prescriptionFinishList = new ArrayList<>();
        }

        prescriptionFinishList.add(prescriptionId);
        redisCache.setCacheObject("drugstore:"+userId+":finish",prescriptionFinishList);

        if (flag){
            //通知电子显示大屏更新信息
            Message msg = new Message("notifyDrugstoreDesktopUpdatePatList",userId,null,null);
            socketServer.onMessage(JSON.toJSONString(msg),null);
        }
        return true;
    }

    @Override
    public boolean finishTakeMedicine(String prescriptionId, Long userId) {
        List<String> prescriptionList = (List<String>) redisCache.getCacheObject("drugstore:"+userId+":finish");
        boolean flag = prescriptionList.remove(prescriptionId);
        if (flag==false){
            return false;
        }
        //更新
        redisCache.setCacheObject("drugstore:"+userId+":finish",prescriptionList);

        //通知电子显示大屏更新信息
        Message msg = new Message("notifyDrugstoreDesktopUpdatePatList",userId,null,null);
        socketServer.onMessage(JSON.toJSONString(msg),null);

        return true;
    }

    @Override
    public Integer getNumberOfVisitsReceived(Long docId) {
        Integer numberOfVisitsReceived = baseMapper.selectNumberOfVisitsReceived(docId);
        if (StringUtils.isEmpty(numberOfVisitsReceived)){
            return 0;
        }
        return numberOfVisitsReceived;
    }
}




